package summary;

import java.util.Iterator;
import java.util.Vector;

public class GradientStatistics {
	long[] maxLocalSkew = null;
		
	public GradientStatistics(Vector<InstantData> instants,int numNodes, long minSecond,long maxSecond,int topology){
		maxLocalSkew = new long[numNodes];
		
		for (int i = 0; i < maxLocalSkew.length; i++) {
			maxLocalSkew[i] = 0;
		}
		
		for (Iterator<InstantData> iterator = instants.iterator(); iterator.hasNext();) {
			InstantData instantData = (InstantData) iterator.next();
			
			if(instantData.second > minSecond && instantData.second < maxSecond){
				for (Iterator<NodeData> iterator2 = instantData.getData().iterator(); iterator2.hasNext();) {
					NodeData node = (NodeData) iterator2.next();
								
					calculateLocalSkew(node, instantData.getData(),topology);
				}
			}				
		}
	}
	
	private void calculateLocalSkew(NodeData node, Vector<NodeData> nodes,int topology){
		
		long local = 0;
		
		for (Iterator<NodeData> iterator = nodes.iterator(); iterator.hasNext();) {
			NodeData nodeToCompare = (NodeData) iterator.next();
						
			boolean isNeighbor = false;
			
			if((node.id == (nodeToCompare.id + 1) )||(node.id == (nodeToCompare.id - 1) )){
				isNeighbor = true;
			}
			else if(topology == InstantStatistics.RING){
				if(nodes.firstElement().equals(node)){
					if(nodes.lastElement().equals(nodeToCompare)){
						isNeighbor = true;
					}
				}
				else if(nodes.lastElement().equals(node)){
					if(nodes.firstElement().equals(nodeToCompare)){
						isNeighbor = true;
					}
				}
			}
			
			if(isNeighbor) {
				long diff = Math.abs(node.clock-nodeToCompare.clock); 
				
				if(diff > 40000000L){
					long result = 0x0FFFFFFFFL;
					result -= node.clock;
					result += nodeToCompare.clock;				
					diff = result;
				}
				
				if(diff > 40000000L){
					long result = 0x0FFFFFFFFL;
					result -= nodeToCompare.clock;
					result += node.clock;				
					diff = result;
				}
				
				if(diff > local){
					local = diff; 
				}	
			}
		}
		
		if(maxLocalSkew[(int) (node.id-1)]<local)
			maxLocalSkew[(int) (node.id-1)]=local;
	}

	public long[] getMaxLocalSkews(){
		return maxLocalSkew;
	}
}
